home *** CD-ROM | disk | FTP | other *** search
- //
- // WAIS PROTOCOL OBJECTIVE-C INTERFACE
- // main header file Wais.h
- //
- // Free software created 1 Feb 1992
- // by Paul Burchard <burchard@math.utah.edu>.
- //
- // This software is distributed at no cost, with no restrictions, and with
- // no guarantees. But it works pretty damn good anyway... :-)
- //
-
- // Incorporating:
- /*
- WIDE AREA INFORMATION SERVER SOFTWARE:
- No guarantees or restrictions. See the readme file for the full standard
- disclaimer.
-
- This is part of the [NeXTstep] user-interface for the WAIS software.
- Do with it as you please.
-
- Version 0.82
- Wed Apr 24 1991
-
- jonathan@Think.COM
-
- */
-
- // Original warranty disclaimer:
- /*
- ------------------------------------------------------------------------
-
- WARRANTY DISCLAIMER
-
- This software was created by Thinking Machines Corporation and is distributed
- free of charge. It is placed in the public domain and permission is granted
- for anyone to use, duplicate, modify and redistribute it.
-
- Thinking Machines Corporation provides absolutely NO WARRANTY OF ANY KIND with
- respect to this software. The entire risk as to the quality and performance
- of this software is with the user. IN NO EVENT WILL THINKING MACHINES
- CORPORATION BE LIABLE TO ANYONE FOR ANY DAMAGES ARISING OUT THE USE OF THIS
- SOFTWARE, INCLUDING, WITHOUT LIMITATION, DAMAGES RESULTING FROM LOST DATA OR
- LOST PROFITS, OR FOR ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES.
-
- ------------------------------------------------------------------------
- */
-
-
-
- //---------------------------------------------------------------------------
- //
- // ABOUT THE WAIS CLASSES.
- //
- // (The class declarations are near the end of this file.)
- //
- // Our object wrapper for WAIS has three classes: WaisQuestion, WaisSource,
- // and WaisDocument. Documents are retrieved from sources. Questions produce
- // a list of documents and relevance scores, when given a string of keywords to
- // match, a list of sources to search, and a list of relevant documents to
- // emulate. Scores are numbers in the range from 0.0 to 1.0, with 1.0 denoting
- // the best-matching document found.
- //
- // To facilitate user manipulation of sources and documents, which can be
- // shared among several questions, WAIS objects can be accessed by string keys
- // (via +objectForKey:). The string key is the full path of the file in which
- // the object is stored---or would be stored upon retrieval. WAIS objects will
- // be automatically loaded from their WAIS structured files as necessary when
- // a key lookup is performed. Note that keys are actually NXAtoms.
- //
- // To support lookup with incomplete keys and creation of objects from
- // incomplete keys, each class also has a folder list (a Storage object of
- // NXAtoms) which is used as a search path. (For creation, the first element
- // of the folder list is used). The folder list is set by the subclasses (see
- // the "Folder" methods below) and initially contains an appropriate subfolder
- // of "~/Library/WAIS/".
- //
- // All WAIS objects contain lists of information fields, which are stored via
- // associative tables connecting field names to values. These info fields
- // encode most of the parameters of the WAIS objects. These info fields, along
- // with any other necessary data, are read from and written to WAIS structured
- // files [see below] with the -readWaisFile and -writeWaisFile methods (which
- // use the key as the file name).
- //
- // If so enabled during compilation [see below], these classes provide support
- // for running WAIS procedures (typically, retrievals and searches) in separate
- // MACH threads. The support has two parts: the first is a set of mutex
- // locking methods, which are also used here internally. The second is a
- // callback method that allows you to send thread-unsafe object messages (such
- // as those involving the AppKit) back to the main thread for execution.
- //
- // Aside from setting up callbacks (if so enabled), these classes use the
- // NeXTstep AppKit only to put up Alert Panels; and even this is only enabled
- // if an NXStringTable of error messages has been established via the class
- // method +setStringTable:.
- //
- // The NXStringTable of error messages is shared among the current classes,
- // so a call to [Wais setStringTable:...] is enough. The following string keys
- // are needed if Alert Panels are desired:
- //
- // "OK"
- // "WAIS Question Error!"
- // "WAIS Source Error!"
- // "WAIS Document Error!"
- // "Can't connect to server %s."
- // "Can't open folder %s."
- // "Can't connect to source %s."
- // "No sources to search."
- // "Bad source %s."
- // "Unknown source %s."
- // "No key words for search."
- // "Buffer overflow: request too large for source %s."
- // "Warning: no information returned from source %s."
- // "Search diagnostics: %s, %s"
- // "Source %s returned bad search response."
- // "Can't form document for headline %s."
- // "Found no documents matching the question."
- // "Found no documents with positive matching scores."
- // "Can't create local document file %s."
- // "Document %s is empty."
- // "Overflow: retrieval request too large for %s."
- // "Warning: missing data for document %s."
- // "Retrieval diagnostics: %s, %s"
- // "Bad %s file format: %s."
- // "Can't read %s file: %s."
- // "Can't create %s file %s."
- // "Error writing %s file %s."
- // "Write error on document %s."
- // "Retrieving document...press to abort"
- // "Retrieving %d documents...press to abort"
- // "Document specification garbled."
- // "No Doc-ID for %s."
- // "Bad document scores."
- //
-
-
- //-----------------------------------------------------------------------
- //
- // Support for multiple MACH Threads.
- //
- // If you want support for threads, make sure WAIS_THREAD_SUPPORT is #defined.
- //
- // This sets up the WAIS classes with locking methods which can be used to help
- // prevent conflicts between multiple threads of execution. These methods are
- // no-ops if thread support is not enabled. If your program uses threads and
- // contains potential conflicts with the operations below, you'll need to
- // frame those operations with the corresponding pair of Wais class locking
- // methods.
- //
- // +lockTransaction/+unlockTransaction
- // Frames all uses of the network for WAIS search and retrieval
- // transactions. (Typically on port 210.)
- //
- // +lockFileIO/+unlockFileIO
- // Frames all reading and writing of files, stderr messages, and so on.
- //
- //
- // The other thing that enabling thread support does is to set up a callback
- // method which lets you send object messages back to the main thread for
- // execution. This done with MACH messaging. If thread support is not enabled
- // the callback just directly performs the object message.
- //
- // +callback:anObject perform:(SEL)aSelector with:anArgument
- //
- // If a thread is aborted in the middle of a locked procedure, you may need
- // to create new mutexes to prevent blockage:
- //
- // +waisNewLocks
- //
- #ifdef WAIS_THREAD_SUPPORT
- #import <cthreads.h>
- #endif
-
-
- // System includes.
- #import <stdio.h>
- #import <ctype.h>
- #import <string.h>
- #import <sys/types.h>
- #import <sys/stat.h>
- #define USE_SYS_DIR
- #import <sys/dir.h>
- #define dirent direct
-
-
- // WAIS library includes.
- #import <ui.h>
- #import <irfileio.h>
- #import <docid.h>
- #import <sockets.h>
- #define WAIS_PROTOCOL_VERSION "2" /* integer-valued string */
-
-
- // Constants.
- // Note: alter these constants with care. Some values seem tied to WAIS lib.
- #define STRINGSIZE 256
- #define MAX_MESSAGE_LEN 16384
- #define MAX_QUERY_SIZE 1000
- #define QUESTION_FILE_VERSION 1
- #define CHARS_PER_PAGE 2000
- #define SEARCH_LIMIT_DEFAULT 30
- #define READ_BUF_SIZE 65535
-
-
- // C utility functions defined in Wais.m.
- extern void ErrorMsg(const char *title, const char *format, ...);
- extern long ReadLongS(char *buffer, FILE *file);
- extern long WriteLongS(char *buffer, FILE *file);
- extern long ReadDoubleS(char *buffer, FILE *file);
- extern long WriteDoubleS(char *buffer, FILE *file);
- extern long ReadListX(FILE *file);
- extern void read_subfield(const char *source, char *key,
- char *value, int value_size);
- extern void replace_controlM(char *buffer, long *length);
- extern any* copy_any(any *thing);
-
-
- // Global variables defined in Wais.m and used by WAIS library.
- extern FILE *logfile;
- extern char *log_file_name;
-
-
- //-----------------------------------------------------------------------
- // Decoding structured WAIS files.
- //
- // WAIS structured files contain a single structure, of the form
- // (:name elements...)
- // where elements... is a sequence composed of: (1) fields, of the form
- // :name data
- // or (2) substructures, of the form
- // :name (:structname elements...)
- // or (3) lists of structures of a single type, of the form
- // :name ( (:structname elements...) (:structname elements...) ...)
- // The decoders give the type, W_FIELD, W_STRUCT, or W_LIST, for each element
- // name.
- //
- // W_FIELDs are read/written as formatted strings by the reader() and writer().
- // These are stored in the WAIS object as a table associating field name to
- // field value. Args of field readers/writers are (annoyingly) arranged thus:
- // 1 long Function(FILE *file)
- // 2 long Function(char *buffer, FILE *file)
- // 3 long Function(char *buffer, FILE *file, int bufsize)
- // (Actually the arg patterns are even less consistent in the WAIS library,
- // so we have replaced ReadLong, WriteLong, ReadDouble, and WriteDouble.)
- // The return values are TRUE, FALSE, or END_OF_STRUCT_OR_LIST.
- //
- // W_STRUCTs are read/written with a recursive call to the -readWaisStruct::::/
- // -writeWaisStruct:::: methods. This allows subclasses of Wais to intercept
- // these calls or make preparations before calling super to do the actual i/o
- // (e.g. creating objects for info to be read into/written from).
- //
- // W_LISTs are handled similarly, except that the recursive call is repeated
- // until a FALSE or END_OF_STRUCT_OR_LIST return. Note that the element name
- // of the list is passed as a method parameter so that subclasses can find the
- // right list of objects in which to store the structures of the list (however
- // be aware that this arg may be NULL).
- //
- // The -readWaisStruct::::/-writeWaisStruct:::: methods should quietly pass
- // over unknown fields and structures if possible, and return TRUE, FALSE, or
- // END_OF_STRUCT_OR_LIST as appropriate. The +fileStructName method should
- // return the structName expected at the beginning of the file for that class,
- // and +fileStructDecoder gives the corresponding WaisDecoder.
- //
-
- typedef struct waisDecoder
- {
- const char *name;
- int elementType;
- const char *structName;
- struct waisDecoder *subDecoder;
- long (*reader)();
- int readArgs;
- long (*writer)();
- int writeArgs;
- unsigned int maxBufSize;
- }
- _WaisDecoder, *WaisDecoder;
-
- #define W_FIELD 0
- #define W_STRUCT 1
- #define W_LIST 2
-
-
- //-----------------------------------------------------------------------
- //
- // Abstract superclass for WAIS objects.
- //
- // See description above.
- //
-
- // Don't change order of includes here.
- #import <objc/Object.h>
- #import <objc/HashTable.h>
- #import <objc/List.h>
- #import <objc/Storage.h>
- #import <appkit/appkit.h>
-
- @interface Wais : Object
- {
- NXAtom key;
- id infoFields;
- }
-
- // Access by object keys. "Folder" methods should be subclassed.
- + objectForKey:(const char *)aKey;
- + objectForCompleteKey:(const char *)aKey;
- - (const char *)key;
- - setKey:(const char *)aKey;
- + waisObjectList;
- + folderList;
- + setFolderList:aList;
- + (const char *)defaultHomeFolder;
-
- // Creating and destroying WAIS objects.
- + initialize;
- - initKey:(const char *)aKey; // uses -setKey:
- - free;
-
- // Editing info fields.
- // Note: key and value strings need not be held constant (they're copied).
- - (const char *)valueForStringKey:(const char *)aKey;
- - (const char *)insertStringKey:(const char *)aKey value:(const char *)aValue;
-
- // Reading/writing WAIS files.
- // +loadFolder: returns List of Wais objects of given type, free it after use.
- // Subclass "Struct" methods as explained above.
- // Subclass +checkFileName: if necessary (default always returns YES).
- - readWaisFile;
- - writeWaisFile;
- + loadFolder:(const char *)folderName;
- - (short)readWaisStruct:(const char *)structName
- forElement:(const char *)elementName
- fromFile:(FILE *)file
- withDecoder:(WaisDecoder)theDecoder;
- - (short)writeWaisStruct:(const char *)structName
- forElement:(const char *)elementName
- toFile:(FILE *)file
- withDecoder:(WaisDecoder)theDecoder;
- + (const char *)fileStructName;
- + (WaisDecoder)fileStructDecoder;
- + (BOOL)checkFileName:(const char *)fileName;
-
- // Routing error messages. Subclass the +errorTitle method.
- + setQuiet:(BOOL)yn;
- + (BOOL)isQuiet;
- + setStringTable:aTable;
- + (const char *)errorTitle;
-
- // Support for multiple threads.
- + lockTransaction;
- + unlockTransaction;
- + lockFileIO;
- + unlockFileIO;
- + callback:anObject perform:(SEL)aSelector with:anArgument;
- + (port_t)callbackPort;
- + waisNewLocks;
-
- @end
-
-
- // Basic WAIS objects and file extensions.
- // (Keep order of includes here too.)
- #define W_S_EXT ".src"
- #define W_D_EXT ".wais"
- #define W_Q_EXT ".qst"
- #import "WaisSource.h"
- #import "WaisDocument.h"
- #import "WaisQuestion.h"
-
-
-
-